﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace PongGame
{
    public class GameManager
    {
        Vector2 ballPosition = new Vector2(0.5f, 0.5f);
        float leftPaddlePosition , rightPaddlePosition;
        int leftPlayerLives, rightPlayerLives;
        bool multiplayer = false;
        Vector2 ballSpeedVector = new Vector2(0, 0);// set to Zero when in menu or game over.
        const float ComputerPaddleSpeed = .5f;
        const float BallSpeedMultiplicator = 0.5f;
        MenuManager menuMgr;
        SoundBank soundBank;


       //constructor
        public GameManager(MenuManager MenuMgr, SoundBank sound)
        {
           menuMgr = MenuMgr;
           soundBank = sound;
        }


        public int LeftPlayerLives
        {
            get { return leftPlayerLives; }
        }

        public int RightPlayerLives
        {
            get { return rightPlayerLives; }
        }

        public Vector2 BallPos
        { get { return ballPosition; } }

        public float LeftPaddlePos
        { get { return leftPaddlePosition; } }

        public float RightPaddlePos
        { get { return rightPaddlePosition; } }

        public bool MultiPlayer
        {
           get { return multiplayer; }
           set { multiplayer = value; }
        }

        public void StartNewGame()
        {
           leftPlayerLives = 3;
           rightPlayerLives = 3;
           leftPaddlePosition = 0.5f;// 0 means top, 1 means bottom.
           rightPaddlePosition = 0.5f;

           StartNewBall();
        }

        public void StartNewBall()
        {
           ballPosition = new Vector2(0.5f, 0.5f);//Middle of the screen
           Random rnd = new Random((int)DateTime.Now.Ticks);
           int direction = rnd.Next(4);
           ballSpeedVector =
               direction == 0 ? new Vector2(1, 0.8f) :
               direction == 1 ? new Vector2(1, -0.8f) :
               direction == 2 ? new Vector2(-1, 0.8f) :
               new Vector2(-1, -0.8f);
        }

        public void StopBall()
        {
            ballSpeedVector = new Vector2(0, 0);
        }

        public void MovePaddles()
        {
           // Move up and down if we press the cursor or gamepad keys.
           if (menuMgr.GamePadUp || menuMgr.KeyBoard.IsKeyDown(Keys.Up))
              rightPaddlePosition -= Game1.DisplacementPerFrame;

           if (menuMgr.GamePadDown || menuMgr.KeyBoard.IsKeyDown(Keys.Down))
              rightPaddlePosition += Game1.DisplacementPerFrame;

           if (multiplayer)
           {
              // Move up and down if we press the cursor or gamepad keys.
              if (menuMgr.GamePad2Up || menuMgr.KeyBoard.IsKeyDown(Keys.W))
                 leftPaddlePosition -= Game1.DisplacementPerFrame;
              if (menuMgr.GamePad2Down || menuMgr.KeyBoard.IsKeyDown(Keys.S) || menuMgr.KeyBoard.IsKeyDown(Keys.O))
                 leftPaddlePosition += Game1.DisplacementPerFrame;
           }
           else
           {
              // Just let the computer follow the ball position
              float computerChange = ComputerPaddleSpeed * Game1.DisplacementPerFrame;
              if (leftPaddlePosition > ballPosition.Y + computerChange)
                 leftPaddlePosition -= computerChange;
              else if (leftPaddlePosition < ballPosition.Y - computerChange)
                 leftPaddlePosition += computerChange;
           }
           // Make sure paddles stay between top and bottom borders of the screen (0 and 1)
           if (leftPaddlePosition < 0)
              leftPaddlePosition = 0;
           if (leftPaddlePosition > 1)
              leftPaddlePosition = 1;
           if (rightPaddlePosition < 0)
              rightPaddlePosition = 0;
           if (rightPaddlePosition > 1)
              rightPaddlePosition = 1;
        }

        public void MoveBall()
        {
           // Ball is stopped and we are in the game? Then start it again.
           if (ballSpeedVector.LengthSquared() == 0 && menuMgr.gameMode == GameMode.Game)
              StartNewBall();

           // Check top and bottom screen border
           if (ballPosition.Y < 0 || ballPosition.Y > 1)
           {
              ballSpeedVector.Y = -ballSpeedVector.Y;
              soundBank.PlayCue("PongBallHit");
           }

           // Check for collisions with the paddles
           // Construct bounding boxes to use the intersection helper method.
           Vector2 ballSize = new Vector2(
               SpriteManager.GameBallRect.Width / 1024.0f, SpriteManager.GameBallRect.Height / 768.0f);
           BoundingBox ballBox = new BoundingBox(
               new Vector3(ballPosition.X - ballSize.X / 2, ballPosition.Y - ballSize.Y / 2, 0),
               new Vector3(ballPosition.X + ballSize.X / 2, ballPosition.Y + ballSize.Y / 2, 0));
           Vector2 paddleSize = new Vector2(
               SpriteManager.GameRedPaddleRect.Width / 1024.0f, SpriteManager.GameRedPaddleRect.Height / 768.0f);
           BoundingBox leftPaddleBox = new BoundingBox(
               new Vector3(-paddleSize.X / 2, leftPaddlePosition - paddleSize.Y / 2, 0),
               new Vector3(+paddleSize.X / 2, leftPaddlePosition + paddleSize.Y / 2, 0));
           BoundingBox rightPaddleBox = new BoundingBox(
               new Vector3(1 - paddleSize.X / 2, rightPaddlePosition - paddleSize.Y / 2, 0),
               new Vector3(1 + paddleSize.X / 2, rightPaddlePosition + paddleSize.Y / 2, 0));

           // Ball hit left paddle?
           if (ballBox.Intersects(leftPaddleBox))
           {
              // Bounce of the paddle (always make positive)
              ballSpeedVector.X = Math.Abs(ballSpeedVector.X);
              // Increase speed a little
              ballSpeedVector *= 1.05f;
              // Did we hit the edges of the paddle?
              if (ballBox.Intersects(new BoundingBox(
                  new Vector3(leftPaddleBox.Min.X - 0.01f, leftPaddleBox.Min.Y - 0.01f, 0),
                  new Vector3(leftPaddleBox.Min.X + 0.01f, leftPaddleBox.Min.Y + 0.01f, 0))))
                 // Bounce of at a more difficult angle for the other player
                 ballSpeedVector.Y = -2;
              else if (ballBox.Intersects(new BoundingBox(
                  new Vector3(leftPaddleBox.Min.X - 0.01f, leftPaddleBox.Max.Y - 0.01f, 0),
                  new Vector3(leftPaddleBox.Min.X + 0.01f, leftPaddleBox.Max.Y + 0.01f, 0))))
                 // Bounce of at a more difficult angle for the other player
                 ballSpeedVector.Y = +2;
              // Play sound
              soundBank.PlayCue("PongBallHit");
           }

           // Ball hit right paddle?
           if (ballBox.Intersects(rightPaddleBox))
           {
              // Bounce of the paddle (always make negative)
              ballSpeedVector.X = -Math.Abs(ballSpeedVector.X);
              // Increase speed a little
              ballSpeedVector *= 1.05f;
              // Did we hit the edges of the paddle?
              if (ballBox.Intersects(new BoundingBox(
                  new Vector3(rightPaddleBox.Min.X - 0.01f, rightPaddleBox.Min.Y - 0.01f, 0),
                  new Vector3(rightPaddleBox.Min.X + 0.01f, rightPaddleBox.Min.Y + 0.01f, 0))))
                 // Bounce of at a more difficult angle for the other player
                 ballSpeedVector.Y = -2;
              else if (ballBox.Intersects(new BoundingBox(
                  new Vector3(rightPaddleBox.Min.X - 0.01f, rightPaddleBox.Max.Y - 0.01f, 0),
                  new Vector3(rightPaddleBox.Min.X + 0.01f, rightPaddleBox.Max.Y + 0.01f, 0))))
                 // Bounce of at a more difficult angle for the other player
                 ballSpeedVector.Y = +2;

              // Play sound
              soundBank.PlayCue("PongBallHit");
           }

           // Update ball position and bounce off the borders
           ballPosition += ballSpeedVector *
               Game1.DisplacementPerFrame * BallSpeedMultiplicator;

           // Ball lost?
           if (ballPosition.X < -0.065f)
           {
              // Play sound
              soundBank.PlayCue("PongBallLost");
              // Reduce number of lives
              leftPlayerLives--;
              // Start new ball
              StartNewBall();
           }
           else if (ballPosition.X > 1.065f)
           {
              // Play sound
              soundBank.PlayCue("PongBallLost");
              // Reduce number of lives
              rightPlayerLives--;
              // Start new ball
              StartNewBall();
           }

           // If either player has no more lives, the other one has won!
           if (menuMgr.gameMode == GameMode.Game &&
               (leftPlayerLives == 0 ||
               rightPlayerLives == 0))
           {
              menuMgr.gameMode = GameMode.GameOver;
              StopBall();
           }
        }

    }
}
